package com.darkness.rpc.framework.protocol.dark;

import com.darkness.rpc.framework.common.Invocation;
import com.darkness.rpc.framework.common.util.ProtostuffUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * @author darkness
 * @time 2022/4/15 10:32
 * @description
 */
public class DarkProtocolDecoder extends ByteToMessageDecoder {

    private int length = 0;

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
        if (in.readableBytes() >= 4) {
            if (length == 0) {
                // 这里判断length=0是因为可能这次过来的数据是上次没读完的数据, 如果上次读过length, 但是没读content, 这次就不能读length了
                // message中, 前面4个字节是int类型, 标志着content的长度, 如果在bytebuf中可读超过4个字节, 就可以将这4个字节拿出来得到一个int, 这个int就是content的长度
                length = in.readInt();
            }
            if (in.readableBytes() < length) {
                // 如果读完一个int, 剩下的字节数小于length, 说明还没从socket缓冲区读进来, 因此不能读, 直接返回, 等待eventpoll的下一次触发
                return;
            }
            byte[] content = new byte[length];
            if (in.readableBytes() >= length){
                in.readBytes(content);
                // 使用ProtoStuff将读取到的字节数组解析成Invocation对象，传递到下一个handler业务处理
                Invocation invocation = ProtostuffUtil.deserializer(content, Invocation.class);
                out.add(invocation);
            }
            // 重置当前处理器对象的length属性
            length = 0;
        }
    }
}
